/**********
@name: editor组件
@describtion: props: title:字段别名 ,value: 字段值
@author:liubingye
@date:2023-02-10 18:36:37
***********/
<template>
  <div class="tinymce-box">
    <Editor
        :id="tinyEditorName"
        v-model="content"
        :init="init"
        tag-name="div"
    />
    <ImageUpload v-if="showAxupImgs" v-model:showDialog="showAxupImgs" :limit="20" @getImage="insertImage" :isToJpg="true"></ImageUpload>
  </div>
</template>

<script>

//引入tinymce编辑器
import Editor from '@tinymce/tinymce-vue'

//引入node_modules里的tinymce相关文件文件
import tinymce from 'tinymce/tinymce' //tinymce默认hidden，不引入则不显示编辑器
import 'tinymce/themes/silver'  //编辑器主题，不引入则报错
import 'tinymce/icons/default'  //引入编辑器图标icon，不引入则不显示对应图标
import 'tinymce/plugins/advlist'; //高级列表
import 'tinymce/plugins/anchor'; //锚点
import 'tinymce/plugins/autolink'; //自动链接
import 'tinymce/plugins/autoresize'; //编辑器高度自适应,注：plugins里引入此插件时，Init里设置的height将失效
import 'tinymce/plugins/autosave'; //自动存稿
import 'tinymce/plugins/charmap'; //特殊字符
import 'tinymce/plugins/code'; //编辑源码
import 'tinymce/plugins/codesample'; //代码示例
import 'tinymce/plugins/directionality'; //文字方向
import 'tinymce/plugins/emoticons'; //表情
import 'tinymce/plugins/fullpage'; //文档属性
import 'tinymce/plugins/fullscreen'; //全屏
import 'tinymce/plugins/help'; //帮助
import 'tinymce/plugins/hr'; //水平分割线
import 'tinymce/plugins/image'; //插入编辑图片
import 'tinymce/plugins/importcss'; //引入css
import 'tinymce/plugins/insertdatetime'; //插入日期时间
import 'tinymce/plugins/link'; //超链接
import 'tinymce/plugins/lists'; //列表插件
import 'tinymce/plugins/media'; //插入编辑媒体
import 'tinymce/plugins/nonbreaking'; //插入不间断空格
import 'tinymce/plugins/pagebreak'; //插入分页符
import 'tinymce/plugins/paste'; //粘贴插件
import 'tinymce/plugins/preview'; //预览
import 'tinymce/plugins/print'; //打印
import 'tinymce/plugins/quickbars'; //快速工具栏
import 'tinymce/plugins/save'; //保存
import 'tinymce/plugins/searchreplace'; //查找替换
import 'tinymce/plugins/tabfocus'; //切入切出，按tab键切出编辑器，切入页面其他输入框中
import 'tinymce/plugins/table'; //表格
import 'tinymce/plugins/template'; //内容模板
import 'tinymce/plugins/textcolor'; //文字颜色
import 'tinymce/plugins/textpattern'; //快速排版
import 'tinymce/plugins/toc'; //目录生成器
import 'tinymce/plugins/visualblocks'; //显示元素范围
import 'tinymce/plugins/visualchars'; //显示不可见字符
import 'tinymce/plugins/wordcount'; //字数统计
import '@npkg/tinymce-plugins/importword' //三方插件导入word
import '@npkg/tinymce-plugins/indent2em'

import {watch, ref, computed} from "vue";
import {convertHexToBase64, parseRtf} from "@/utils/tools";
import {useStore} from "vuex";
import {singleUpload, splitUpload} from "@/utils/upload";
import { getImageSize } from "@/utils/tools"

export default {
  name: 'TEditor',
  components: {
    Editor
  },
  props: {
    editorName: {
      type: String,
      default: 'myEdit'
    },
    title: {
      type: String,
      default: ''
    },
    modelValue: {
      type: String,
      default: ''
    },
    minHeight: {
      type: Number,
      default: 400
    },
    maxHeight: {
      type: Number,
      default: 0
    },
    imgTaskEnd: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue','update:imgTaskEnd'],
  setup(props,context) {
    const imgTaskListStart = ref(0)
    const imgTaskListEnd = ref(0)
    const imgTaskEnd = computed({
      get: () => {
        return props.imgTaskEnd
      },
      set: (val) => {
        context.emit('update:imgTaskEnd',val)
      }
    })
    const store = useStore()
    const singleActionUrl = ref(store.state.content.singleActionUrl)
    const splitActionUrl = ref(store.state.content.splitActionUrl)
    const init = {
      language_url: process.env.BASE_URL+'tinymce/langs/zh_CN.js',  //引入语言包文件
      language: 'zh_CN',  //语言类型

      skin_url: process.env.BASE_URL+'tinymce/skins/ui/oxide',  //皮肤：浅色

      plugins: 'autoresize print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ',  //插件配置
      toolbar: ['importword axupimgs media link table | code undo redo | formatselect fontselect fontsizeselect','lineheight bullist numlist | forecolor backcolor bold italic underline strikethrough | alignleft aligncenter alignright alignjustify outdent indent indent2em | blockquote subscript superscript'],  //工具栏配置，设为false则隐藏
      menubar: 'edit insert view format tools table', //菜单栏配置，设为false则隐藏，不配置则默认显示全部菜单，也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
      menu: {
        edit: { title: '编辑', items: 'undo redo | cut copy paste pastetext | selectall' },
        insert: { title: '插入', items: 'link image  |  hr' },
        view: { title: '查看', items: 'visualaid' },
      },
      min_height: props.minHeight,
      max_height: props.maxHeight,
      extended_valid_elements: "svg[*],foreignobject[*],defs[*],pattern[*],desc[*],metadata[*],g[*],mask[*],path[*],line[*],marker[*],rect[*],circle[*],ellipse[*],polygon[*],polyline[*],linearGradient[*],radialGradient[*],stop[*],image[*],view[*],text[*],textPath[*],title[*],tspan[*],glyph[*],symbol[*],switch[*],use[*]",
      fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px',  //字体大小
      font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',  //字体样式
      lineheight_formats: "0.5 0.8 1 1.2 1.5 1.75 2 2.5 3 4 5",  //行高配置，也可配置成"12px 14px 16px 20px"这种形式
      placeholder: '在这里输入文字',
      branding: false,  //tiny技术支持信息是否显示
      resize: false,  //编辑器宽高是否可变，false-否,true-高可变，'both'-宽高均可，注意引号
      elementpath: false,  //元素路径是否显示
      content_css: process.env.BASE_URL+'tinymce/tinycontent.css',
      content_style: "img {max-width:100%;}",  //直接自定义可编辑区域的css样式
      paste_data_images: true,  //图片是否可粘贴
      convert_urls: false,
      // eslint-disable-next-line no-unused-vars
      images_upload_handler: async (blobInfo, success, failure, progress) => {
        imgTaskListStart.value++
        let option = {
          file:new File([blobInfo.blob()], blobInfo.filename(), { type: "image/png" })
        }
        let res = {}
        if (option.file.size > 5 * 1024 *1024) {
          // 切片
          res = await splitUpload(option.file, splitActionUrl.value , () => {} , 5 * 1024 * 1024)
        } else {
          let data = new FormData()
          data.append('file', option.file)
          // 获取图片文件的宽高属性
          const {width, height} = await getImageSize(option.file)
          data.append('cropWidth', width)
          data.append('cropHeight', height)
          data.append('scaledWidth', width)
          data.append('scaledHeight', height)
          data.append('startX', 0)
          data.append('startY', 0)
          data.append('path', 'public')
          data.append('type', 0)
          res = await singleUpload(data, singleActionUrl.value, () => {} )
        }
        if(res.data.url){
          success(res.data.url);
        }
        imgTaskListEnd.value++
        if(imgTaskListStart.value == imgTaskListEnd.value){
          imgTaskEnd.value = true
        }
      },
      init_instance_callback: function(editor){
        editor.on('paste', evt => {
          const clipboardData = evt.clipboardData
          const isImage = clipboardData.types.length && clipboardData.types.join('').includes('Files')
          if (!isImage) {
            //------------------------粘贴word核心代码开始-------------------------
            const hexStrings = parseRtf(evt.clipboardData.getData('text/rtf'))
            // 获取base64图片数据
            const base64Images = hexStrings.map((hexObj) => {
              return convertHexToBase64(hexObj.hex)
            })
            setTimeout(() => {
              const wordImages = tinymce.activeEditor.dom.doc.querySelectorAll('img[src*="file://"]')
              wordImages.forEach((item, index) => {
                item.src = `data:${hexStrings[index].type};base64,${base64Images[index]}`;
                tinymce.activeEditor.uploadImages()
              })
            }, 200)
            //------------------------粘贴word核心代码结束-------------------------
            return
          }
          const file = clipboardData.files[0]
          if (!file || !file.name || !(file.name.toLowerCase().indexOf('.png') !== -1 || file.name.toLowerCase().indexOf('.gif') !== -1
              || file.name.toLowerCase().indexOf('.jpeg') !== -1 || file.name.toLowerCase().indexOf('.jpg') !== -1)) {
            this.$message.error('您粘贴的不是图片请检查！')
            return
          }
          if (file.size / 1024 / 1024 > 5) {
            this.$message.error('上传失败，图片大小请控制在 5M 以内')
            return
          }
        })

      },
      setup: (editor) => {
        editor.ui.registry.addButton('axupimgs',{
          text: `<i class="iconfont">&#xe609;</i>`,
          tooltip: '批量上传',
          onAction: () => {
            showAxupImgs.value = true
          }
        })
        editor.on('init', function () {
          // 获取编辑器内容
          var content = editor.getContent();
          // 判断内容中是否包含<img>标签
          if (!content.includes('<img')) {
            // 内容中不包含图片
            imgTaskEnd.value = true
          }
        });
      }
    }
    tinymce.init
    const tinyEditorName = computed(() => {return props.editorName})
    const revert_data = content => {
      context.emit('update:modelValue', content.value);
    };
    const content = ref(props.modelValue);
    const modelTitle = ref(props.title)
    watch(() => props.modelValue,() => {
      content.value = props.modelValue
    })
    watch(
        () => content.value,
        () => {
          revert_data(content);
        },
    );

    const showAxupImgs = ref(false)
    const insertImage = (imgList) => {
      let imgContent = ``
      imgList.forEach(item => {
        let _img = `<p><img src="${item.url}" /></p>`
        imgContent = imgContent + _img
      })
      tinymce.editors[tinyEditorName.value].insertContent(imgContent+'<p></p>')
    }

    return {
      content,
      modelTitle,
      init,
      tinyEditorName,
      showAxupImgs,
      insertImage
    }
  }
}
</script>

<style lang="scss" scoped>
.tinymce-box{
  width: 100%;
  .editor-header{
    height: 60px;
    line-height: 60px;
    h2{
      font-size: 18px;
      color: #333333;
    }
  }
}
::v-deep(.axupimg-box .el-dialog__body){
  padding: 0;
}
.axupimg-box{
  .inner-axupimg-box{
    display: flex;
    height: 450px;
    .axupimg-upload-box{
      width: 520px;
      height: 100%;
      .local-upload{
        padding: 10px;
        width: 500px;
        .local-upload-list{
          height: 330px;
          display: flex;
          flex-wrap: wrap;
          position: relative;
          align-content: flex-start;
          &>div{
            height: 110px;
            width: 110px;
            margin-right: 10px;
            margin-bottom: 10px;
            background-color: #F0F2F7;
          }
          li{
            height: 110px;
            width: 110px;
            box-sizing: border-box;
            list-style: none;
            border: 1px solid #dcdfe6;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            border-radius: 5px;
            cursor: pointer;
            .img-box{
              height: 108px;
              width: 108px;
              display: flex;
              justify-content: center;
              align-items: center;
              img{
                max-width: 108px;
                max-height: 108px;
              }
            }
            .progress-box{
              width: 100px;
              position: absolute;
              bottom: 5px;
            }
            .remove-upload{
              color: $placeholderColor;
              position: absolute;
              right: 5px;
              top: 8px;
              cursor: pointer;
              display: none;
            }
            .choose-check{
              position: absolute;
              left: 5px;top: 0;
            }
            &:hover{
              .remove-upload{
                display: block;
              }
            }
            &.is-choose{
              border-color: $mainColor;
            }
          }
        }
      }
      .online-upload{
        padding: 10px;
        width: 500px;
        .online-upload-list{
          display: flex;
          flex-wrap: wrap;
          height: 375px;
          .online-upload-item{
            height: 115px;width: 115px;
            border-radius: 6px;
            background-color: $borderColor;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 10px;
            margin-bottom: 10px;
            cursor: pointer;
            box-sizing: border-box;
            img{
              max-width: 100%;
              max-height: 100%;
            }
            &:nth-child(4n){
              margin-right: 0;
            }
            &.is-choose{
              border: 1px solid $mainColor;
            }
          }
        }
      }
    }
    .axupimg-list-box{
      width: 180px;
      height: 100%;
      border-left: 1px solid #dcdfe6;
      box-sizing: border-box;
      padding: 10px;
      p{
        margin-bottom: 10px;
      }
      .chose-img-list{
        height: 400px;
        justify-content: center;
        flex-direction: column;
        .chose-img-box{
          height: 130px;width: 145px;
          display: flex;
          align-items: center;
          justify-content: center;
          background-color: #F0F2F7;
          margin-bottom: 10px;
          border-radius: 6px;
          img{
            max-height: 100%;
            max-width: 100%;
          }
        }
      }
    }
  }
}

</style>

